using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using TimeTravel.XnaLibrary;
using System.IO;
using TimeTravel.XnaLibrary.GamePlay;
using TimeTravel.XnaLibrary.UI;

namespace CreatingGenresDemoGame
{
	/// <summary>
	/// This is the main type for your game
	/// </summary>
	public class TimeTravel : Game
	{
		#region Fields
		GraphicsDeviceManager graphics;
		SpriteBatch spriteBatch;
		Texture2D mousePointer, warPathTexture, upgradeBoostTexture;
		MouseState previousMouseState;
		Dictionary<string, Screen> screens = new Dictionary<string, Screen>();
		SpriteFont andyBold32, arial14;

		GameMode gameMode;
		GameState gameState;
		int activePlayerIndex = 1;
		Button draggedButton;
		Canvas mouseContainer;
		Race race1, race2;
		GameSettings settings;
		TurnHistory history;

		Tuple<Button, int> unitToBeSendBackInTime;
		Button unitToBeKilled;

		Label mainInfoLabel;
		FadingLabel errorLabel;
		StackPanel warPathPanel;

		Vector2 arenaPosition = new Vector2(350, 200);
		int arenaLength = 640 - 64;
		int turnsPerUpgrade = 5;
		int textureHeight = 64;
		int scrollingSpeed = 20;

		#endregion
		
		public TimeTravel()
		{
			graphics = new GraphicsDeviceManager(this);
			Content.RootDirectory = "Content";
			
			IsFixedTimeStep = false;
			Window.AllowUserResizing = true;
			Window.Title = "Time Travel";
			graphics.PreferredBackBufferWidth = 1024;
			graphics.PreferredBackBufferHeight = 768;
			//graphics.IsFullScreen = true;
		}

		/// <summary>
		/// Allows the game to perform any initialization it needs to before starting to run.
		/// This is where it can query for any required services and load any non-graphic
		/// related content.  Calling base.Initialize will enumerate through any components
		/// and initialize them as well.
		/// </summary>
		protected override void Initialize()
		{
			// TODO: Add your initialization logic here
			previousMouseState = Mouse.GetState();
			base.Initialize();
		}

		/// <summary>
		/// LoadContent will be called once per game and is the place to load
		/// all of your content.
		/// </summary>
		protected override void LoadContent()
		{
			// Create a new SpriteBatch, which can be used to draw textures.
			spriteBatch = new SpriteBatch(GraphicsDevice);
			andyBold32 = Content.Load<SpriteFont>("AndyBold32");
			arial14 = Content.Load<SpriteFont>("Arial14");
			mousePointer = Content.Load<Texture2D>("Mouse pointer");
			warPathTexture = Content.Load<Texture2D>("War path");
			upgradeBoostTexture = Content.Load<Texture2D>(@"GameUI\Power up");
			using (StreamReader file = new StreamReader(@"Settings\Config.txt"))
			{
				settings = Parser.ParseGameSetings(file);
				Player.StartingCoins = settings.StartingGold;
				Player.StartingFood = settings.StartingFood;
				Player.FoodPerTile = settings.FoodPerTile;
				AI.StartingTimeMana = settings.StartingMana;
			}
			using (StreamReader file = new StreamReader(@"Settings\Races.txt"))
			{
				Race[] races = Parser.ParseRaces(file, this.Content, 4);
				race1 = races[0];
				race2 = races[1];
			}
			CreateStartScreen();
			CreateBattleScreen();
		}
		
		#region CreateUI
		private void CreateStartScreen()
		{
			Screen startScreen = new Screen();
			Point welcomeLabelPos = new Point(150, 75);
			int buttonOffset = 150;

			Label welcomeLabel = new Label(andyBold32);
			welcomeLabel.TextColor = Color.White;
			welcomeLabel.Text = "Welcome to Time Travel!\nPlease select gamemode.";
			welcomeLabel.Location.Location = welcomeLabelPos;

			Button withoutTimeTravelButton = new Button();
			withoutTimeTravelButton.Texture = Content.Load<Texture2D>(@"StartScreen\AI vs AI");
			withoutTimeTravelButton.Location = withoutTimeTravelButton.Texture.Bounds;
			withoutTimeTravelButton.Location.Offset(welcomeLabelPos.X, welcomeLabelPos.Y + buttonOffset);
			withoutTimeTravelButton.MouseClick += new Control.ControlEventHandler((source, args) =>
			{
				gameMode = GameMode.AIvsAIWithoutTT;
				EnterBattleScreen();
				(Screen.Active.Controls["TimeMana1"] as TextContainer).IsVisible = false;
				(Screen.Active.Controls["TimeMana2"] as TextContainer).IsVisible = false;
			});

			Button withTimeTravelButton = new Button();
			withTimeTravelButton.Texture = Content.Load<Texture2D>(@"StartScreen\AI vs AI - TT");
			withTimeTravelButton.Location = withTimeTravelButton.Texture.Bounds;
			withTimeTravelButton.Location.Offset(welcomeLabelPos.X, withoutTimeTravelButton.Location.Bottom);
			withTimeTravelButton.MouseClick += new Control.ControlEventHandler((source, args) =>
			{
				gameMode = GameMode.AIVsAIWithTT;
				EnterBattleScreen();
			});

			startScreen.Controls.Add("HumanVsAIButton", withoutTimeTravelButton);
			startScreen.Controls.Add("withTimeTravelButton", withTimeTravelButton);
			startScreen.Controls.Add("WelcomeLabel", welcomeLabel);
			screens.Add("start", startScreen);
		}

		private void EnterBattleScreen()
		{
			AI bot1, bot2;
			using (StreamReader reader = new StreamReader(@"Settings\AIsettings1.txt"))
			{
				bot1 = new AI(race1, 0, Parser.ParseAIOrders(reader));
			}
			using (StreamReader reader = new StreamReader(@"Settings\AIsettings2.txt"))
			{
				bot2 = new AI(race2, arenaLength, Parser.ParseAIOrders(reader));
			}
			if (gameMode == GameMode.AIvsAIWithoutTT)
			{
				bot1.TimeMana = 0;
				bot2.TimeMana = 0;
			}
			bot1.Enemy = bot2;
			bot2.Enemy = bot1;
			history = new TurnHistory(bot1, bot2);
			gameState = GameState.StillPlaying;
			Screen.Active = screens["battle"];
			mainInfoLabel.Text = GameMessages.StillPlaying;
		}

		private void CreateBattleScreen()
		{
			Screen battleScreen = new Screen();

			Point timeManaPosition = new Point(35,100);
			GenerateTimeMana(battleScreen, timeManaPosition, 1);
			timeManaPosition = new Point(GraphicsDevice.DisplayMode.Width - 100, 100);
			GenerateTimeMana(battleScreen, timeManaPosition, 2);

			mainInfoLabel = new Label(andyBold32);
			Vector2 textSize = andyBold32.MeasureString(GameMessages.Player1Turn);
			mainInfoLabel.Position = new Point(GraphicsDevice.DisplayMode.Width / 2 - (int)textSize.X / 2, 75);
			mainInfoLabel.Name = "MainInfoLabel";

			errorLabel = new FadingLabel(arial14, TimeSpan.FromSeconds(5));
			errorLabel.Position = new Point(50, 400);
			errorLabel.Name = "ErrorLabel";

			warPathPanel = new StackPanel(StackPanelOrientation.Vertical);
			warPathPanel.Offset = 25;
			warPathPanel.Name = "WarPathPanel";
			warPathPanel.Location = new Rectangle((int)arenaPosition.X, (int)arenaPosition.Y,
				warPathTexture.Bounds.Width, warPathTexture.Bounds.Height * 4);			

			Button backButton = new Button();
			backButton.Texture = Content.Load<Texture2D>("back");
			backButton.Location = backButton.Texture.Bounds;
			backButton.Location.Offset(warPathPanel.Location.Right + 200, warPathTexture.Bounds.Height + 200);
			backButton.MouseClick += new Control.ControlEventHandler((source, args) =>
			{
				Restart();
				Screen.Active = screens["start"];
			});
			backButton.Name = "BackButton";

			Button butterflyButton = new Button();
			butterflyButton.Texture = Content.Load<Texture2D>(@"GameUI\Butterfly");
			butterflyButton.Location = butterflyButton.Texture.Bounds;
			butterflyButton.Location.Offset(100, 300);
			butterflyButton.Name = "ButterflyButton";
			butterflyButton.MouseDragStarted += new Control.ControlEventHandler((source, args) =>
			{
				draggedButton = source as Button;
				draggedButton.CaptureMouse();
			});
			butterflyButton.MouseDragEnded += CreateButterflyEffect;

			battleScreen.Controls.Add(warPathPanel.Name, warPathPanel);
			battleScreen.Controls.Add(mainInfoLabel.Name, mainInfoLabel);
			battleScreen.Controls.Add(errorLabel.Name, errorLabel);
			battleScreen.Controls.Add(backButton.Name, backButton);
			battleScreen.Controls.Add(butterflyButton.Name, butterflyButton);
			screens.Add("battle", battleScreen);
		}

		private void GenerateTimeMana(Screen battleScreen, Point position, int playerIndex)
		{
			//Create an button representing the time manaCost for each player.
			Button timeMana = new Button();
			timeMana.Texture = Content.Load<Texture2D>(@"GameUI\Time mana");
			timeMana.Font = andyBold32;
			timeMana.RelativeTextPosition = RelativeTextPosition.CenteredLeft;
			timeMana.Location = timeMana.Texture.Bounds;
			timeMana.Text = AI.StartingTimeMana.ToString();
			int additionalXOffset = playerIndex == 2 ? 0 : (int)timeMana.TextSize.X;
			timeMana.Location.Offset(position.X + additionalXOffset, position.Y);
			timeMana.Name = "TimeMana" + playerIndex;

			battleScreen.Controls.Add(timeMana.Name, timeMana);
		}

		private void Restart()
		{
			warPathPanel.Clear();
			warPathPanel.CalculateVisibleContent();
			gameState = GameState.StillPlaying;
		}
		#endregion

		/// <summary>
		/// Allows the game to run logic such as updating the world,
		/// checking for collisions, gathering input, and playing audio.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Update(GameTime gameTime)
		{
			// Allows the game to exit
			if (Keyboard.GetState().IsKeyDown(Keys.Escape))
				this.Exit();

			if (!IsActive)
				return;
			MouseState currentMouseState = Mouse.GetState();

			if (unitToBeSendBackInTime != null)
			{
				SendUnitBackInTime(unitToBeSendBackInTime.Item1, unitToBeSendBackInTime.Item2);
				unitToBeSendBackInTime = null;
			}
			if (unitToBeKilled != null)
			{
				KillUnit(unitToBeKilled);
				unitToBeKilled = null;
			}

			Screen.Active.Update(gameTime, currentMouseState, previousMouseState);
			errorLabel.Update(gameTime);
			if (Screen.Active == screens["battle"])
			{
				ScrollWarPanel(currentMouseState, Keyboard.GetState());
				if (gameState == GameState.StillPlaying)
				{
					if (history.CurrentTurn % turnsPerUpgrade == 0)
					{
						history.Boosts.Add(new UpgradeBoost(arenaLength));
					}
					ExecuteAICycle();
					CheckForGameOver();
				}
				(Screen.Active.Controls["TimeMana1"] as TextContainer).Text = history.Bot1.TimeMana.ToString();
				(Screen.Active.Controls["TimeMana2"] as TextContainer).Text = history.Bot2.TimeMana.ToString();
			}

			//if (Control.MouseHolder != null)
			//    Mouse.SetPosition(Control.CapturedMousePosition.X, Control.CapturedMousePosition.Y);

			if (currentMouseState.LeftButton == ButtonState.Released && Control.MouseHolder != null)
				Control.MouseHolder.ReleaseCapture();
			previousMouseState = currentMouseState;
			base.Update(gameTime);
		}

		#region GameplayUpdateHelpers
		private void SendUnitBackInTime(Button button, int turnTo)
		{
			//Get the active player, save his current manaCost
			AI active = activePlayerIndex == 1 ? history.Bot1 : history.Bot2;
			int currentTimeMana = active.TimeMana;

			int turnFrom, unitOwnerIndex;
			GetButtonInformation(button, out turnFrom, out unitOwnerIndex);
			int manaCost;
			if (turnFrom > turnTo)
			{
				manaCost = settings.RewingUnitCost + (turnFrom - turnTo - 1) * 5;
			}	
			else
			{
				manaCost = settings.ForwardUnitCost + (turnTo - turnFrom - 1) * 5;
			}
			if (currentTimeMana < manaCost)
			{
				string errorMessage;
				if (turnFrom > turnTo)
					errorMessage = GameMessages.GetNotEnoughManaMessage(manaCost, currentTimeMana, TimeManipulationType.RewindUnit);
				else
					errorMessage = GameMessages.GetNotEnoughManaMessage(manaCost, currentTimeMana, TimeManipulationType.ForwardUnit);
				errorLabel.Text = errorMessage;
				return;
			}
			currentTimeMana -= manaCost;

			//Restore the state back and update the current mana
			history.SendUnitInTime(button.Tag as Unit, activePlayerIndex, turnTo);
			history.RestoreState(turnTo);
			active = activePlayerIndex == 1 ? history.Bot1 : history.Bot2;
			active.TimeMana = currentTimeMana;

			//Add a new unit button to the canvas 
			Canvas parent = warPathPanel.GetChild("WarPathCanvas" + turnTo) as Canvas;
			AddUnitButton(parent, active, activePlayerIndex, active.ActiveUnits.Count - 1);
			RefreshUI(parent);
			gameState = GameState.StillPlaying;
		}

		private void KillUnit(Button button)
		{
			//Get the active player, save his current manaCost
			AI active = activePlayerIndex == 1 ? history.Bot1 : history.Bot2;
			if (active.TimeMana < settings.KillEnemyCost)
			{
				errorLabel.Text = GameMessages.GetNotEnoughManaMessage(settings.KillEnemyCost, active.TimeMana, 
					TimeManipulationType.KillEnemy);
				return;
			}

			int currentTimeMana = active.TimeMana - settings.KillEnemyCost;

			//Restore the state back and update the current mana
			int turnIndex, unitOwnerIndex;
			GetButtonInformation(button, out turnIndex, out unitOwnerIndex);
			history.KillUnit(button.Tag as Unit, unitOwnerIndex, turnIndex);
			history.RestoreState(turnIndex);

			active = activePlayerIndex == 1 ? history.Bot1 : history.Bot2;
			active.TimeMana = currentTimeMana;

			//Clean up the war path panel and the war path canvas this unit belongs to
			Canvas parent = warPathPanel.GetChild("WarPathCanvas" + turnIndex) as Canvas;
			parent.RemoveChild(button.Name);
			RefreshUI(parent);
			gameState = GameState.StillPlaying;
		}

		private void CreateButterflyEffect(object source, EventArgs args)
		{
			draggedButton = null;
			if (gameState != GameState.StillPlaying && mouseContainer != null)
			{
				AI active = activePlayerIndex == 1 ? history.Bot1 : history.Bot2;
				if (active.TimeMana < settings.ButterflyCost)
				{
					errorLabel.Text = GameMessages.GetNotEnoughManaMessage(settings.ButterflyCost, active.TimeMana, 
						TimeManipulationType.Butterfly);
					return;
				}
				int currentTimeMana = active.TimeMana - settings.ButterflyCost;

				//Change the random number generator and restore the state, return the butterfly button to its default position
				int turn = Int32.Parse(mouseContainer.Name.Replace("WarPathCanvas", ""));
				Player.Rng = new Random();
				Button butterfly = source as Button;
				butterfly.Location.Location = new Point(100, 300);
				history.RestoreState(turn);
				RefreshUI(mouseContainer);
				gameState = GameState.StillPlaying;

				//Update the time mana value
				active = activePlayerIndex == 1 ? history.Bot1 : history.Bot2;
				active.TimeMana = currentTimeMana;
			}
		}

		private void RefreshUI(Canvas parent)
		{
			parent.UpdateLocation();
			warPathPanel.RemoveAfterChild(parent.Name);
			warPathPanel.Reorder();
		}

		private void ExecuteAICycle()
		{
			//Run orders for both bots, save the current state and draw it
			history.Bot1.ExecuteOrders();
			history.Bot1.UpdateUnits(history.Boosts);
			history.Bot2.ExecuteOrders();
			history.Bot2.UpdateUnits(history.Boosts);
			AddWarPath();
			history.SaveState();
		}

		private void CheckForGameOver()
		{
			CheckVictoryCondition();
			if (gameState != GameState.StillPlaying)
			{
				if (gameState == GameState.Player1Wins)
				{
					//If history.Bot2 still has manaCost left, he should use to try alter the course of the battle
					if (history.Bot2.TimeMana >= AI.MinimumTimeTravelCost)
					{
						mainInfoLabel.Text = GameMessages.Player2Turn;
						activePlayerIndex = 2;
					}
					else
					{
						mainInfoLabel.Text = GameMessages.Player1Wins;
					}
				}
				else if (gameState == GameState.Player2Wins)
				{
					//If history.Bot1 still has manaCost left, he should use to try alter the course of the battle
					if (history.Bot1.TimeMana >= AI.MinimumTimeTravelCost)
					{
						mainInfoLabel.Text = GameMessages.Player1Turn;
						activePlayerIndex = 1;
					}
					else
					{
						mainInfoLabel.Text = GameMessages.Player2Wins;
					}
				}
			}
		}

		private void CheckVictoryCondition()
		{
			bool player1HasValidMoves = true;
			bool player2HasValidMoves = true;
			if (history.Bot1.ActiveUnits.Count == 0 && history.Bot1.SleepingUnits.Count == 0)
			{
				player1HasValidMoves = false;
				//Go through all units the race can build
				for (int i = 0; i < race1.Units.Count; i++)
				{
					//If the bot has enough gold to build at least one unit, the flag will be set to true
					player1HasValidMoves = player1HasValidMoves || history.Bot1.CanBuyUnit(i);
				}
			}
			if (history.Bot2.ActiveUnits.Count == 0 && history.Bot2.SleepingUnits.Count == 0)
			{
				player2HasValidMoves = false;
				for (int i = 0; i < race2.Units.Count; i++)
				{
					player2HasValidMoves = player2HasValidMoves || history.Bot2.CanBuyUnit(i);
				}
			}

			if (player1HasValidMoves && !player2HasValidMoves)
				gameState = GameState.Player1Wins;
			else if (!player1HasValidMoves && player2HasValidMoves)
				gameState = GameState.Player2Wins;
		}

		#endregion

		#region UIUpdateHelpers

		private void ScrollWarPanel(MouseState currentMouseState, KeyboardState currentKeyboardState)
		{
			if (currentMouseState.ScrollWheelValue > previousMouseState.ScrollWheelValue)
			{
				warPathPanel.VisibilityPosition += scrollingSpeed;
			}
			else if (currentMouseState.ScrollWheelValue < previousMouseState.ScrollWheelValue)
			{
				warPathPanel.VisibilityPosition -= scrollingSpeed;
			}
			else if (currentKeyboardState.IsKeyDown(Keys.Down))
			{
				warPathPanel.VisibilityPosition += (int) (scrollingSpeed * 0.4f);
			}
			else if (currentKeyboardState.IsKeyDown(Keys.Up))
			{
				warPathPanel.VisibilityPosition -= (int) (scrollingSpeed * 0.4f);
 			}
			warPathPanel.CalculateVisibleContent();
		}

		private void AddWarPath()
		{
			//Create the canvas hosting the turnTo. Add MouseEnter and MouseLeave handlers in order to keep track of the current canvas
			//above which the mouse is hovering
			Canvas warPathCanvas = new Canvas();
			warPathCanvas.Name = "WarPathCanvas" + history.CurrentTurn;
			warPathCanvas.Location = warPathTexture.Bounds;
			warPathCanvas.Location.Height = textureHeight * 2;
			warPathCanvas.MouseEnter += new Control.ControlEventHandler((source, args) =>
			{
				mouseContainer = source as Canvas;
			});
			warPathCanvas.MouseLeave += new Control.ControlEventHandler((source, args) =>
			{
				if (mouseContainer == source)
					mouseContainer = null;
			});

			//Create the background
			Button warPath = new Button();
			warPath.Texture = warPathTexture;
			warPath.Location = warPath.Texture.Bounds;
			warPath.Location.Height = textureHeight * 2;
			warPath.Font = andyBold32;
			warPath.Text = history.CurrentTurn.ToString();
			warPath.RelativeTextPosition = RelativeTextPosition.Centered;
			warPath.Name = "Path" + history.CurrentTurn;
			warPathCanvas.AddChild(warPath, Point.Zero);
			//Create buttons for each unit and add them to the canvas
			for	(int i = 0; i < history.Bot1.ActiveUnits.Count; i++)
			{
				AddUnitButton(warPathCanvas, history.Bot1, 1, i);
			} 
			for (int i = 0; i < history.Bot2.ActiveUnits.Count; i++)
			{
				AddUnitButton(warPathCanvas, history.Bot2, 2, i);
			}
			for (int i = 0; i < history.Boosts.Count; i++)
			{
				AddUpgradeBoost(warPathCanvas, i);
			}
			warPathPanel.AddChild(warPathCanvas);
		}

		private void AddUnitButton(Canvas warPathCanvas, Player player, int playerIndex, int unitIndex)
		{
			//Create a button representing the unit and adds it to the specified canvas
			Button unitButton = new Button();
			unitButton.Texture = player.ActiveUnits[unitIndex].ActiveIcon;
			Color tinting = Color.White;
			if (player.ActiveUnits[unitIndex].IsWeakened)
				tinting = Color.DarkSlateBlue;
			tinting.A = (byte)((player.ActiveUnits[unitIndex].Health / player.ActiveUnits[unitIndex].MaxHealth) * 255);
			unitButton.TintingColor = tinting;
			unitButton.Location = unitButton.Texture.Bounds;
			unitButton.Location.Height = textureHeight;
			if (gameMode == GameMode.AIVsAIWithTT)
			{
				unitButton.MouseDragStarted += UnitDragStarted;
				unitButton.MouseDragEnded += UnitDragEnded;
				unitButton.MouseDrag += UnitDrag;
				unitButton.Tag = new Unit(player.ActiveUnits[unitIndex]);
			}
			string turn = warPathCanvas.Name.Replace("WarPathCanvas", "");
			unitButton.Name = "Unit_" + unitIndex + "_" + playerIndex + "_" + turn;
			warPathCanvas.AddChild(unitButton, new Point(player.ActiveUnits[unitIndex].Position, unitButton.Texture.Bounds.Bottom));
		}

		private void AddUpgradeBoost(Canvas warPathCanvas, int boostIndex)
		{
			Button boostButton = new Button();
			boostButton.Texture = upgradeBoostTexture;
			boostButton.Location = upgradeBoostTexture.Bounds;
			boostButton.Location.Height = textureHeight / 2;
			boostButton.Name = "Boost" + boostIndex;
			warPathCanvas.AddChild(boostButton, new Point(history.Boosts[boostIndex].Position, boostButton.Texture.Bounds.Bottom * 3));
		}

		private void UnitDragStarted(object source, EventArgs args)
		{
			//Set the dragged unit
			draggedButton = source as Button;
			draggedButton.CaptureMouse();
		}

		private void UnitDrag(object source, EventArgs args)
		{
			return;
			MouseState currentState = Mouse.GetState();
			Button button = source as Button;
			int distY = currentState.Y - previousMouseState.Y; //Control.CapturedMousePosition.Y;

			warPathPanel.VisibilityPosition += distY * 3;
		}

		private void UnitDragEnded(object source, EventArgs args)
		{
			//Remove the dragged unit and if the mouse is currently hovering over a war path canvas, bring the time back
			//to the turnTo that the canvas represents
			draggedButton = null;
			Control.MouseHolder.ReleaseCapture();
			Button button = source as Button;
			int turnFrom, unitOwnerIndex;
			GetButtonInformation(button, out turnFrom, out unitOwnerIndex);
			if (mouseContainer != null)
			{
				int turnTo = Int32.Parse(mouseContainer.Name.Replace("WarPathCanvas", ""));
				if (unitOwnerIndex == activePlayerIndex && turnTo != turnFrom)
				{
					unitToBeSendBackInTime = new Tuple<Button, int>(button, turnTo);
				}
			}
			else if (unitOwnerIndex != activePlayerIndex)
			{
				unitToBeKilled = button;
			}
		}

		/// <summary>
		/// Gets information from the button`s name. Turn represents the turn of which the button is part of and 
		/// UnitOwnerIndex represents the index of the player owning the unit that the button represents.
		/// </summary>
		/// <param name="button">The button to get info from</param>
		/// <param name="turn">Represents the turn of which the button is part of.</param>
		/// <param name="unitOwnerIndex">Represents the index of the player owning the unit that the button represents</param>
		private static void GetButtonInformation(Button button, out int turn, out int unitOwnerIndex)
		{
			int lastDashIndex = button.Name.LastIndexOf("_");
			turn = Int32.Parse(button.Name.Remove(0, lastDashIndex + 1));
			string[] unitInfo = button.Name.Split('_');
			unitOwnerIndex = Int32.Parse(unitInfo[2]);
		}

		#endregion
		
		/// <summary>
		/// This is called when the game should draw itself.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Draw(GameTime gameTime)
		{
			GraphicsDevice.Clear(Color.CornflowerBlue);
			spriteBatch.Begin();

			Screen.Active.Draw(spriteBatch);
			DrawDraggedButton();
			DrawMousePointer();

			spriteBatch.End();
			base.Draw(gameTime);
		}

		private void DrawDraggedButton()
		{
			if (Screen.Active == screens["battle"] && draggedButton != null)
			{
				draggedButton.Location.Location = new Point(Mouse.GetState().X, Mouse.GetState().Y);
				draggedButton.Draw(spriteBatch);
			}
		}

		#region DrawingHelpers

		private void DrawMousePointer()
		{
			if (Control.MouseHolder == null)
				spriteBatch.Draw(mousePointer, new Vector2(previousMouseState.X, previousMouseState.Y), Color.White);
		}
		#endregion
	}
}
